package com.java.basis.collection;



import org.springframework.util.StopWatch;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ArrayList与LinkedList对比
 * 结论：
 * 1.当根据下标随机访问的时候，ArrayList比较块
 * 2.当再头部添加元素的时候，LinkedList比较块
 * 3.当向尾部插入数据时候，ArrayList反而比想象中的快，性能比LinkedList还要快
 * 4.当向中间插入数据的时候，两个都不是特别快，但是相较而言，ArrayList会快一点
 * 所以再选择中，基本上都可以直接使用ArrayList，因为LinkedList也就只有头部的插入比较好了
 */
public class ArrayListVsLinkedList {
    public static void main(String[] args) {
        int n = 10000;
        for (int i = 0; i < 5; i++) {
            int[] array = randomArray(n);
            List<Integer> list1 = Arrays.stream(array).boxed().collect(Collectors.toList());
            LinkedList<Integer> list2 = new LinkedList<>(list1);
//            randomAccess(list1, list2, n/2);
//            addFirst(list1, list2);
//            addLast(list1, list2);
            addMid(list1, list2, n/2);

        }
    }

    private static void addMid(List<Integer> list1, LinkedList<Integer> list2, int mid) {
        StopWatch sw = new StopWatch();
        sw.start("ArrayList");
        list1.add(mid, 10);
        sw.stop();

        sw.start("LinkedList");
        list2.add(mid,10);
        sw.stop();
        System.out.println(sw.prettyPrint());
    }

    private static void addLast(List<Integer> list1, LinkedList<Integer> list2) {
        StopWatch sw = new StopWatch();
        sw.start("ArrayList");
        list1.add(10);
        sw.stop();

        sw.start("LinkedList");
        list2.addLast(10);
        sw.stop();
        System.out.println(sw.prettyPrint());
    }

    private static void addFirst(List<Integer> list1, LinkedList<Integer> list2) {
        StopWatch sw = new StopWatch();
        sw.start("ArrayList");
        list1.add(0, 10);
        sw.stop();

        sw.start("LinkedList");
        list2.addFirst(10);
        sw.stop();
        System.out.println(sw.prettyPrint());

    }

    private static void randomAccess(List<Integer> list1, LinkedList<Integer> list2, int mid) {
        StopWatch sw = new StopWatch();
        sw.start("ArrayList");
        list1.get(mid);
        sw.stop();

        sw.start("LinkedList");
        list2.get(mid);
        sw.stop();
        System.out.println(sw.prettyPrint());
    }

    private static int[] randomArray(int n) {
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = (int) (Math.random()*n);
        }
//        System.out.println("arr = " + Arrays.toString(arr));
        return arr;
    }
}
